/*
@Time : 2019/4/24 0024 19:33
@Author : visons
*/
package game

import (
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"encoding/json"
	"errors"
	"gitee.com/visons/gopkg/logger"
)

func AnalyzeWxData(encryptedData string, ivData string, sessionKey string) (*WxDataSt, error) {
	cipherText, err := base64.StdEncoding.DecodeString(encryptedData)
	if err != nil {
		//logger.Error(err)
		return nil, err
	}

	iv, err := base64.StdEncoding.DecodeString(ivData)
	if err != nil {
		//logger.Error(err)
		return nil, err
	}
	logger.Info("iv %s", string(iv))

	key, err := base64.StdEncoding.DecodeString(sessionKey)
	if err != nil {
		//logger.Error(err)
		return nil, err
	}

	logger.Info("key %s", string(key))

	result, err := AesCBCDncrypt(cipherText, key, iv)
	if err != nil {
		//logger.Error(err)
		return nil, err
	}

	logger.Info(string(result))

	wxData := WxDataSt{}
	err = json.Unmarshal(result, &wxData)
	if err != nil {
		return nil, err
	}

	return &wxData, nil
}

// 解密
func AesCBCDncrypt(encryptData, key, iv []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}
	blockSize := block.BlockSize()
	if len(encryptData) < blockSize {
		errors.New("ciphertext too short")
	}
	if len(encryptData)%blockSize != 0 {
		errors.New("ciphertext is not a multiple of the block size")
	}
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(encryptData, encryptData)
	// 解填充
	encryptData = PKCS7UnPadding(encryptData)
	return encryptData, nil
}

//去除填充
func PKCS7UnPadding(origData []byte) []byte {
	length := len(origData)
	unpadding := int(origData[length-1])
	return origData[:(length - unpadding)]
}
